import sys
from fastapi import FastAPI, Request, APIRouter, Form
from fastapi.responses import PlainTextResponse
from core.WXBizMsgCrypt3 import WXBizMsgCrypt
import xml.etree.cElementTree as ET
import uvicorn
from pydantic import BaseModel
from typing import Dict, Any
import requests
import ast
import core.wechat_utils as wechat_utils
from core.other_utils import contains_keyword
from db.database_utils import DatabaseUtils

router = APIRouter()
app = FastAPI()

# sToken = "ev6a2hEYWbaIgOnL31Yqp9c4jHlN"
# sEncodingAESKey = "Q7pmwlXHvmfItplmRWMnb7KGu72LVh8qZOmXPdmdzHc"
# sCorpID = "ww195f7d1dc767e06a"
# corpsecret = "ZNbMHigfJHbNThz0YGL1VNEhj1uXCMI--0YdxpbYVpY"

sToken = None
sEncodingAESKey = None
sCorpID = None
corpsecret = None

API_URL = "https://power-api.yingdao.com/oapi/power/v1/rest/flow/4c9d6a7e-1c0b-409b-92d1-c881461acef5/execute"
headers = {
    'Authorization': 'Bearer AP_g3VxPbKcjMEEgLGW',
    'Content-Type': 'application/json'
}


def query(payload):
    response = requests.post(API_URL, headers=headers, json=payload)
    return response.json()


@router.get("/wework")
def verify_callback_url(request: Request):

    query_params = request.query_params
    sVerifyMsgSig = query_params.get("msg_signature")
    sVerifyTimeStamp = query_params.get("timestamp")
    sVerifyNonce = query_params.get("nonce")
    sVerifyEchoStr = query_params.get("echostr")
    wxcpt = WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID)

    ret, sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sVerifyEchoStr)
    if ret != 0:
        print("ERR: VerifyURL ret: " + str(ret))
        return {"errcode": ret}
    response = PlainTextResponse(sEchoStr)
    return response


class Item(BaseModel):
    data: Dict[str, Any]


@router.post("/wework")
async def read_item(request: Request):
    global query

    # 获取相关参数
    msg_signature = request.query_params.get('msg_signature')
    timestamp = request.query_params.get('timestamp')
    nonce = request.query_params.get('nonce')

    # 解析信息
    wxcpt = WXBizMsgCrypt(sToken, sEncodingAESKey, sCorpID)
    body = await request.body()
    body_str = body.decode('utf-8')
    ret, sMsg = wxcpt.DecryptMsg(body_str, msg_signature, timestamp, nonce)
    print("----------------------------------")

    # 获取详细信息
    xml_tree = ET.fromstring(sMsg)
    content = xml_tree.findtext("Content")
    MsgType = xml_tree.findtext("MsgType")
    Event = xml_tree.findtext("Event")
    token = xml_tree.findtext("Token")
    openKfId = xml_tree.findtext("OpenKfId")

    # 判断为应用消息还是客服消息
    # 1.应用消息
    if content is not None:
        if not contains_keyword(content, "切换+"):
            output = query({"input": {"input_text_0": content}})
            output = output["data"]["result"]['output_text_0']
        else:
            global API_URL
            global headers
            text_list = content.split('+')
            print(text_list)
            API_URL = text_list[1]
            headers = ast.literal_eval(text_list[2])
            print(API_URL)
            print(headers)
            output = "OK,切换成功"
        print(API_URL)
        print(content)
    # 2，客服消息
    elif MsgType == "event" and Event == "kf_msg_or_event":
        output = "客服消息"
        # 获取调用接口凭证
        token_cache_file = "access_token.json"
        access_token = wechat_utils.get_access_token(sCorpID, corpsecret, token_cache_file)
        # 建立数据库链接
        db = DatabaseUtils('mysql://root:123456@localhost:3306/weixin')
        # 读取上一次next_cursor，用于消息游标
        cursors = db.execute_query("SELECT * FROM Cursors ORDER BY created_at DESC LIMIT 1;")[0][1]
        # 获取消息
        json_text = wechat_utils.get_message(access_token, cursors, token, 20, 0, openKfId)
        next_cursor = json_text["next_cursor"]
        msg_list = json_text["msg_list"]

        # next_cursor写入数据库
        query = f"""
        INSERT INTO Cursors (next_cursor)
        VALUES ('{next_cursor}')
        """
        # 消息入库
        inserted_id_1 = db.execute_insert(query)

        for msg in msg_list:
            if msg["msgtype"] == "text":
                print(msg["msgid"], msg["open_kfid"], msg["external_userid"], msg["send_time"], msg["origin"],
                      msg["msgtype"], msg["text"]["content"])
                send_result = wechat_utils.send_message_text(access_token, msg["external_userid"], msg["open_kfid"],
                                                             "MSGID",
                                                             "你购买的物品已发货，可点击链接查看物流状态http://work.weixin.qq.com/xxxxxx")
                print(send_result)
                query = f"""
                INSERT INTO Messages (msgid, open_kfid, external_userid, send_time, origin, msgtype, content)
                VALUES ('{msg["msgid"]}', '{msg["open_kfid"]}', '{msg["external_userid"]}', {msg["send_time"]}, {msg["origin"]}, '{msg["msgtype"]}', '{msg["text"]["content"]}')
                """
                # 执行插入语句
                inserted_id = db.execute_insert(query)
                # 打印插入后的主键值
                print("主键：" + str(inserted_id))
    else:
        output = "这个类型的文件暂时没有做处理"
        # print(output)
    # print(MsgType,Event)
    # print(sMsg,ret)
    print("----------------------------------")

    # 构建消息
    sRespData = "<xml><ToUserName>ww1436e0e65a779aee</ToUserName><FromUserName>ChenJiaShun</FromUserName><CreateTime" \
                ">1476422779</CreateTime><MsgType>text</MsgType><Content>" + output + \
                "</Content><MsgId>1456453720</MsgId><AgentID>1000002</AgentID></xml>"
    # sRespData = "<xml><Encrypt><![CDATA["+msg_encrypt+"]]></Encrypt><MsgSignature><![CDATA[
    # "+msg_signature+"]]></MsgSignature><TimeStamp>"+timestamp+"</TimeStamp><Nonce><![CDATA[
    # "+nonce+"]]></Nonce></xml>" 消息加密
    ret, sEncryptMsg = wxcpt.EncryptMsg(sRespData, nonce, timestamp)

    # 加密失败
    if ret != 0:
        print("ERR: EncryptMsg ret: " + str(ret))
        sys.exit(1)
    # 加密成功
    else:
        # 响应数据
        response = PlainTextResponse(sEncryptMsg)
        return response


# 配置信息录入
@router.post("/verification_config_message")
async def verification_config_message(
        url: str = Form(...),  # 必填字段，对应前端 input 的 name="url"
        token: str = Form(...),
        corpID: str = Form(...), # 必填字段，对应前端 input 的 name="token"
        EncodingAESKey: str = Form(...)  # 必填字段，对应前端 input 的 name="EncodingAESKey"
):
    sToken = token
    sEncodingAESKey = EncodingAESKey
    sCorpID = corpID

    table_name = 'sys_config'
    columns = ['config_key', 'config_value']
    rows = [
        ('Alice', 'alice@example.com'),
        ('Bob', 'bob@example.com'),
        ('Charlie', 'charlie@example.com')
    ]

    insert_flag = DatabaseUtils('mysql://root:123456@124.70.50.228:3306/weixin').execute_bulk_insert(table_name, columns, rows)

    if insert_flag:
        return {
            "status": "success",
            "data": {
                "url": url,
                "token": token,
                "EncodingAESKey": EncodingAESKey
            }
        }
    else:
        return {
            "status": "fail",
            "data": {
                "url": url,
                "token": token,
                "EncodingAESKey": EncodingAESKey
            }
        }

# if __name__ == "__main__":
#     uvicorn.run("my_fastapi:app", host="0.0.0.0", port=8000)
